package com.siki.salessystemoauth2server.service.impl;

import cn.hutool.core.lang.Assert;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.siki.salessystemcommon.entity.Role;
import com.siki.salessystemcommon.entity.User;
import com.siki.salessystemcommon.entity.enumeration.AccountTypeEnum;
import com.siki.salessystemcommon.mapper.RoleMapper;
import com.siki.salessystemcommon.mapper.UserMapper;
import com.siki.salessystemoauth2server.dto.RegisteredAccountDTO;
import com.siki.salessystemoauth2server.service.AccountService;
import com.siki.salessystemoauth2server.util.DigestUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author Siki
 * @date 2020/12/27
 */
@Service
@RequiredArgsConstructor
public class AccountServiceImpl implements AccountService {

    private final UserMapper userMapper;
    private final RoleMapper roleMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void registered(RegisteredAccountDTO dto) throws Exception {
        QueryWrapper<User> userQw = new QueryWrapper<>();
        userQw.lambda().eq(User::getAccount, dto.getAccount());
        User user = userMapper.selectOne(userQw);
        Assert.isTrue(user == null, "用户名已存在");
        Map<String, Object> map = new HashMap<>(16);
        user = new User();
        List<Integer> roleIds = new ArrayList<>();
        switch (AccountTypeEnum.valueOf(dto.getAccountType())) {
            case SALES_ADMIN:
                roleIds.add(1);
            case SALES:
                roleIds.add(2);
                break;
            case CLIENT:
                roleIds.add(3);
                break;
            case DEPOT_ADMIN:
                roleIds.add(4);
                break;
            case PRO_ADMIN:
                roleIds.addAll(Arrays.asList(1, 2, 3, 4, 5));
                break;
            default:
                throw new RuntimeException("身份信息错误");
        }
        user.setAccount(dto.getAccount()).setPassword(new BCryptPasswordEncoder()
                .encode(DigestUtil.encrypt(dto.getPassword())));
        userMapper.insert(user);
        map.put("userId", user.getId());
        map.put("roleIds", roleIds);
        userMapper.saveUserAndRole(map);
    }

    @Override
    public void deleteAccount(String id) {
        // TODO: 2020/12/4 @Siki: 这里效率有点低,重复查询了一次,做了判空操作,但实际上没必要,可以后期优化
        userMapper.deleteById(getUserById(id).getId());
    }

    private User getUserById(String id) {
        return Optional.ofNullable(userMapper.selectById(id))
                .orElseThrow(() -> new RuntimeException("该id:" + id + "有误"));
    }
}
